﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace QLab.UX.Forms.Controls
{
    public partial class Console : RichTextBox
    {
        private string consoleText;
        private bool shoudWriteConsoleText = false;
        private bool shoudMoveCousorToEnd = false;
        private int consoleCursorPostition = 0;

        public Console()
        {
            InitializeComponent();
            this.Text = ">>";
            this.SelectionStart = this.Text.Length;
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            if (this.shoudWriteConsoleText)
            {
                this.Text = this.consoleText;
                if (shoudMoveCousorToEnd)
                {
                    this.SelectionStart = this.Text.Length;
                    this.SelectionLength = 0;
                }
                else
                {
                    this.SelectionStart = this.consoleCursorPostition;
                    this.SelectionLength = 0;
                }
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (this.InLastRow(this.SelectionStart, e.KeyCode))
            {
                if (e.KeyCode == Keys.Enter)
                {
                    int begin = this.Text.LastIndexOf("\n>>") + 3;
                    string command = this.Text.Substring(begin);

                    this.OnCommandExecuted(command);

                    this.consoleText = this.Text + Environment.NewLine + ">>";
                    this.shoudWriteConsoleText = true;
                    this.shoudMoveCousorToEnd = true;
                }
            }
            else
            {
                this.consoleText = this.Text;
                this.shoudWriteConsoleText = true;
                this.consoleCursorPostition = this.SelectionStart;
            }
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);
            this.shoudWriteConsoleText = false;
            this.shoudMoveCousorToEnd = false;
        }

        private bool InLastRow(int position, Keys key)
        {
            if (position > this.Text.LastIndexOf("\n>>") +
                (key == Keys.Back ? 3 : 2))
                return true;
            return false;
        }

        public delegate void CommandExecutedDelegate(object sender, CommandExecutedEventArgs e);
        public event CommandExecutedDelegate CommandExecuted = null;
        private void OnCommandExecuted(string command)
        {
            if (this.CommandExecuted != null)
                this.CommandExecuted(this, new CommandExecutedEventArgs(command));
        }
    }

    public class CommandExecutedEventArgs : EventArgs
    {
        public CommandExecutedEventArgs(string command)
        {
            this.command = command;
        }

        private string command;
        public string Command
        {
            get { return this.command; }
        }
    }
}